package com.syxx.oa.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.IdentityService;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessDefinitionQuery;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.identity.Group;
import org.jbpm.api.identity.User;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;

import com.syxx.oa.domain.ApproveInfo_1;
import com.syxx.oa.domain.EmpUser;
import com.syxx.oa.domain.Employee;
import com.syxx.oa.domain.NodeAuthority;
import com.syxx.oa.domain.PersonnelRequirement;
import com.syxx.oa.domain.Tuser;
import com.syxx.oa.utils.StringUtils;
import com.syxx.oa.utils.SystemConstant;
import com.test.jbpm.Pager;
import com.test.jbpm.PagerContext;
import com.test.jbpm.dao.impl.BaseDao;

@Repository
public class PersonnelRequirementDao extends BaseDao {
private RepositoryService repositoryService;
	
	private ExecutionService executionService;
	
	private TaskService taskService;
	
	private IdentityService identityService;
	
	private EmployeeDao employeeDao;
	
	private NodeAuthorityDao nodeAuthorityDao;
	
	private ApproveDao1 approveDao1;
	
	@Autowired
	public void setApproveDao1(ApproveDao1 approveDao1) {
		this.approveDao1 = approveDao1;
	}

	@Autowired
	public void setNodeAuthorityDao(NodeAuthorityDao nodeAuthorityDao) {
		this.nodeAuthorityDao = nodeAuthorityDao;
	}

	@Autowired
	public void setEmployeeDao(EmployeeDao employeeDao) {
		this.employeeDao = employeeDao;
	}

	@Autowired
	public void setRepositoryService(RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}
	
	@Autowired
	public void setExecutionService(ExecutionService executionService) {
		this.executionService = executionService;
	}
	
	@Autowired
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}
	
	@Autowired
	public void setIdentityService(IdentityService identityService) {
		this.identityService = identityService;
	}

	public void addOrUpdate(PersonnelRequirement perReq) {
		getHibernateTemplate().saveOrUpdate(perReq);
	}

	public void del(Long perReqId) {
		getHibernateTemplate().delete(getHibernateTemplate().load(PersonnelRequirement.class, perReqId)	);
	}

	@SuppressWarnings("unchecked")
	public Pager<PersonnelRequirement> findMyPersonnelRequirementList(Long creatorId) {
		String hql = "from PersonnelRequirement tt where tt.createEmp.empId=? order by tt.createTime desc";
		return findData(hql, creatorId);
	}

	public PersonnelRequirement findTroubleTicketById(Long perReqId) {
		return (PersonnelRequirement) getHibernateTemplate().load(PersonnelRequirement.class, perReqId);
	}

	/* (non-Javadoc)
	 * @see com.bwie.pmes.dao.TroubleTicketDao#dispatch(java.lang.Long)
	 */
	public void dispatch(Long perReqId) {
		
		
		try {
			//取得最新版本的流程
			/*ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
					.processDefinitionName(SystemConstant.billNames.personnelRequirement.toString())
					.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)
					.page(0, 1)
					.uniqueResult();
			*/	
			//根据id取得请假单
			PersonnelRequirement troubleTicket= (PersonnelRequirement)getHibernateTemplate().load(PersonnelRequirement.class, perReqId);
			Employee curEmp =  troubleTicket.getCreateEmp();
			if(curEmp==null){
				return;
			}
			String groupName = "parentLeader";
			Group group = identityService.findGroupById(groupName);
			if(group==null){//查询上级主管领导
				identityService.createGroup(groupName);
				List<Employee> parentEmps = employeeDao.findParentEmpByDep(curEmp.getDepartment().getDepId());
				for (Employee paemp : parentEmps) {
					identityService.createUser(paemp.getEmpId().toString(),paemp.getEmpName() ,paemp.getDepartment().getDepName());
					// 将afei加入sjzgld_f组  
					identityService.createMembership(paemp.getEmpId().toString(), groupName);  
				}
			}
			
			Map<String,Object> map = new HashMap<String, Object>();
			map.put("currentUser", curEmp.getEmpId().toString());
			Employee depMarster = employeeDao.findMaxLevEmpByEmp(curEmp);//部门经理
			EmpUser empUser = new EmpUser();
			empUser.setUserId(depMarster.getEmpId().toString());
			empUser.setUserName(depMarster.getEmpName());
			map.put("depMarster", empUser);
			
			
			//人力资源部人员
			groupName = "hrGroup";
			group = identityService.findGroupById(groupName);
			if(group==null){
				identityService.createGroup(groupName);
				List<Employee> hrs = employeeDao.findEmpByDepCode(SystemConstant.HR_DEPT_CODE);
				for (Employee emp : hrs) {
					identityService.createUser(emp.getEmpId().toString(),emp.getEmpName() ,emp.getDepartment().getDepName());
					// 将afei加入sjzgld_f组  
					identityService.createMembership(emp.getEmpId().toString(), groupName);  
				}
			}
			
			
			//人力资源部主管领导人员
			Employee hrz = employeeDao.findMaxLevByDepCode(SystemConstant.HR_DEPT_CODE);
			empUser = new EmpUser();
			empUser.setUserId(hrz.getEmpId().toString());
			empUser.setUserName(hrz.getEmpName());
			map.put("hrMarster", empUser);
			//副总
			groupName = "viceGeMaster";
			group = identityService.findGroupById(groupName);
			if(group==null){
				identityService.createGroup(groupName);
				List<Employee> viceGeMasters = employeeDao.findEmpsBylevCode(SystemConstant.VICE_GE_Master);
				for (Employee emp : viceGeMasters) {
					identityService.createUser(emp.getEmpId().toString(),emp.getEmpName() ,emp.getDepartment().getDepName());
					// 将afei加入sjzgld_f组  
					identityService.createMembership(emp.getEmpId().toString(), groupName);  
				}
			}
			
			
			
			//总经理
			List<Employee> geMasters = employeeDao.findEmpsBylevCode(SystemConstant.GE_Master);
			Employee geMaster = geMasters.get(0);
			empUser = new EmpUser();
			empUser.setUserId(geMaster.getEmpId().toString());
			empUser.setUserName(geMaster.getEmpName());
			map.put("geMaster", empUser);
			
			ProcessInstance processInstance = executionService.startProcessInstanceByKey(SystemConstant.billNames.personnelRequirement.toString(),map);
			troubleTicket.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
			/*****************节点权限设置begin************************/
			List<NodeAuthority> nodeList = nodeAuthorityDao.findByPname(SystemConstant.billNames.personnelRequirement.toString());
			if(nodeList==null || nodeList.size()==0){
				NodeAuthority nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("部门经理");
				nodeT.setFieldName("personnelReq.depMgrOpinion");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("上级主管");
				nodeT.setFieldName("personnelReq.leaOption");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("人力资源部");
				nodeT.setFieldName("personnelReq.hrOption");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("人力资源部主管领导");
				nodeT.setFieldName("personnelReq.hrLeaOption");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("副总");
				nodeT.setFieldName("personnelReq.viceGeMgrOption");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("副总");
				nodeT.setFieldName("personnelReq.viceGeMgrSign");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("总经理");
				nodeT.setFieldName("personnelReq.geMgrOption");
				nodeAuthorityDao.addOrUpdate(nodeT);
				
				nodeT = new NodeAuthority();
				nodeT.setProcessName(SystemConstant.billNames.personnelRequirement.toString());
				nodeT.setNodeName("总经理");
				nodeT.setFieldName("personnelReq.geMgrSign");
				nodeAuthorityDao.addOrUpdate(nodeT);
			}
			/*****************节点权限设置end************************/

			
			//取得当前执行Execution
			ExecutionImpl executionImpl = (ExecutionImpl)processInstance;
			
			//设置请假单的状态为当前流程所处于的活动名称
			troubleTicket.setStatus(executionImpl.getActivityName());
			
			//将请假单信息设置到流程变量中
			Map<String, String> variables = new HashMap<String, String>();
			variables.put("personnelRequirementId", troubleTicket.get_id().toString());
			//processInstance和executionImpl的id是一样的,executionImpl实现了processInstance
			executionService.setVariables(executionImpl.getId(), variables);
			
			completeTask(perReqId, curEmp.getEmpId(), null,null);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Pager<PersonnelRequirement> findApprovingPersonnelRequirementList(
			Long approverId) {
		try {
			//访问JBPM4取得待审任务
			List<Task> taskList = taskService.findPersonalTasks(approverId.toString());
			//////////////////begin//////////////////////
			List<Task> groupTask = taskService.findGroupTasks(approverId.toString());
			taskList.addAll(groupTask);
			/////////////////end///////////////////////
			//根据待审任务，取得每个任务对应的流程变量的值（请假单id）
			//将请假单号统一放到一个集合中
			final List<Long> troubleTicketList = new ArrayList<Long>();
			for (Task task : taskList) {
				String temId = (String) taskService.getVariable(task.getId(),
						"personnelRequirementId");
				if (temId == null || "".equals(temId)) {
					continue;
				}
				troubleTicketList.add(Long.valueOf(temId));
			}
			//根据取得的请假单号，查询请假单
			// from TroubleTicket tt where tt.id in(?,?,?,?) order by tt.happenTime desc
			StringBuilder sbHql = new StringBuilder();
			if (troubleTicketList.size() != 0) {
				sbHql.append("from PersonnelRequirement tt where tt._id in(");
				for (int i = 0; i < troubleTicketList.size(); i++) {
					sbHql.append("?");
					if (i < (troubleTicketList.size() - 1)) {
						sbHql.append(",");
					}
				}
				sbHql.append(") ");
				sbHql.append(" order by tt.createTime desc");
				System.out.println(sbHql);
				return findData(sbHql.toString(), troubleTicketList);
			} else {
				return new Pager<PersonnelRequirement>();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new Pager<PersonnelRequirement>();
	}

	public void completeTask(Long troubleTicketId, Long approverId,Boolean isagree,Long approId) {
		//取得审批人的任务
		
		try {
			List<Task> taskList = taskService.findPersonalTasks(approverId.toString());
			
			////////////////////////////begin/////////////////////////////////
			List<Task> groupTask = taskService.findGroupTasks(approverId.toString());  
			if(groupTask != null && groupTask.size()>0){
				taskList.addAll(groupTask);
			}
			////////////////////////////end/////////////////////////////////
			
			//当前请假单对应的task
			Task currentTask = null;
			for (Task task : taskList) {
				String tId = (String) taskService.getVariable(task.getId(), "personnelRequirementId");
				if(tId == null || "".equals(tId)){
					continue;
				}
				
				if (Long.valueOf(tId)-troubleTicketId==0) {
					/////////////////////////////////////////
					try {
						if(task.getAssignee() == null || "".equals(task.getAssignee())){
							taskService.takeTask(task.getId(), approverId.toString());
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					//////////////////////////////////////////
					currentTask = task;
					break;
				}
			}
			//取得请假单
			PersonnelRequirement curBill = (PersonnelRequirement)getHibernateTemplate().load(PersonnelRequirement.class, Long.valueOf(troubleTicketId));
			String status = curBill.getStatus();
			if(StringUtils.isBlank(status)){
				throw new Exception("审批单据不存在");
			}
			if("制单人".equals(status)){
				
			}else {
				if(approId == null || approId == 0L){
					throw new Exception("当前审批意见Id不存在");
				}
				ApproveInfo_1 approve = approveDao1.findById(approId);
				if(approve == null || approve.get_id() == null || approve.get_id()==0L){
					throw new Exception("当前审批意见不存在");
				}
				String curUName = approve.getApprover().getEmpName();
				String approOption = approve.getDesc();
				if(StringUtils.isBlank(curUName)){
					throw new Exception("当前审批人不存在");
				}
				if(isagree == null){
					throw new Exception("当前审批人审批意图不明确");
				}
				if("部门经理".equals(status)){
					curBill.setDepMgrOpinion(approOption);
				}else if("上级主管领导".equals(status)){
					curBill.setLeaOption(approOption);
				}else if("人力资源部".equals(status)){
					curBill.setHrOption(approOption);
				}else if("人力资源部主管领导".equals(status)){
					curBill.setHrLeaOption(approOption);
				}else if("副总".equals(status)){
					curBill.setViceGeMgrOption(approOption);
					curBill.setViceGeMgrSign(isagree ? curUName : null);
				}else if("总经理".equals(status)){
					curBill.setGeMgrOption(approOption);
					curBill.setGeMgrSign(isagree ? curUName : null);
				}
			}
			if (currentTask != null) {
				//判断是同意还是拒绝
				if(isagree != null){
					String to_where = isagree ? "agree" : "reject";
					Map<String, String> map = new HashMap<String, String>();
					map.put("isagree", to_where);
					taskService.setVariables(currentTask.getId(), map);
				}
				
				//完成任务
				taskService.completeTask(currentTask.getId());
				
				//取得当前任务对应的流程实例
				ProcessInstance processInstance = executionService.findProcessInstanceById(currentTask.getExecutionId());
				//如果流程没有结束
				if(processInstance != null) {
					//取得当前执行Execution
					ExecutionImpl executionImpl = (ExecutionImpl)processInstance;
					//设置请假单的状态为活动名称
					curBill.setStatus(executionImpl.getActivityName());
				}else {
					//设置请假单的状态为完成
					curBill.setStatus(PersonnelRequirement.END);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	

	@SuppressWarnings("unchecked")
	public Pager<PersonnelRequirement> findApprovedTroubleTicketList(final Long approverId) {
		List<PersonnelRequirement> troubleTicketList = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				return session.createQuery("select distinct ai.perReq from ApproveInfo_1 ai where ai.approver.empId=? order by ai.approveTime desc")
							.setParameter(0, approverId)
							.setFirstResult(PagerContext.getOffset())
							.setMaxResults(PagerContext.getPageSize())
							.list();
			}
		});
		
		Long total = (Long)getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				return session.createQuery("select count(distinct ai.perReq) from ApproveInfo_1 ai where ai.approver.empId=?")
							.setParameter(0, approverId)
							.uniqueResult();
			}
		});
		Pager<PersonnelRequirement> pager = new Pager<PersonnelRequirement>();
		pager.setData(troubleTicketList);
		pager.setTotal(total.intValue());
		return pager;
	}
}
